<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用canvas 绘图 WebGL上下文</title>
    <style>
        div {
            display: inline-block;
        }

        canvas {
            background-color: #f1f1f1
        }
    </style>
</head>

<body>
    <p>绘制图像</p>
    <div>
        <img src="./../../images/User.png" alt="" class="img">
        <img src="./../../images/sort_desc.png" alt="" class="img">
        <canvas id="drawing" width="200" height="200">
            使用canvas绘图
        </canvas>
        <canvas id="drawing2" width="200" height="200">
            使用canvas绘图
        </canvas>
        <canvas id="drawing3" width="200" height="200">
            使用canvas绘图
        </canvas>
    </div>
</body>
<!-- 分别使用 attribute、uniform 在这两个值类型关键字之后 是数据类型和变量名-->
<!-- 每一个着色器都有一个main方法，该方法在绘图期间反复执行 -->
<script type="x-webgl/x-vertex-shader" id="vertexShader">
    attribute vec2 aVertexPosition;
    void main(){
        gl_Position=vec4(aVertexPosition,0.0,1.0);
    }
</script>
<script type="x-webgl/x-fragment-shader" id="fragmentShader">
    uniform vec4 uColor;
    void main(){
        gl_FragColor=uColor;
    }
</script>
<script>
    window.onload = function () {
       
        (function () {
            var drawing=document.getElementById('drawing');
            if(drawing.getContext){
                var gl=drawing.getContext('experimental-webgl');
                if(gl){
                    console.log("支持gl");
                    
                    // 实际操作WebGl之前使用某种颜色清除canvas
                    // 传入红，绿，蓝，透明度 都为0-1之间的值表示最终颜色的强度
                    gl.clearColor(0,0,0,0.5) //black;

                    // 调用clear 传入COLOR_BUFFER_BIT 告诉应该使用上面定义的颜色来填充画布
                    gl.clear(gl.COLOR_BUFFER_BIT);
                    
                    // 开始绘图之前必须先定义webgl的视口
                    // 使用整个画布作为webgl的视口 不同于canvas 的是原点坐标（0,0）在左下角
                    gl.viewport(0,0,drawing.width,drawing.height);
                    
                    // 顶点信息保存在js类型化数组中，使用之前必须转换到webgl的缓冲区中
                    // 创建webgl的缓冲区
                    var buffer=gl.createBuffer();

                    // 绑定到webgl的上下文
                    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);

                    // 用数据来填充缓冲区 一般是使用Float32Array来保存顶点信息
                    // STATIC_DRAW 指定使用缓冲区的方式 ：数据只加载一次，在多次绘图中使用
                    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([0,0.5,1]),gl.STATIC_DRAW);
                    
                    // 释放内存
                    // gl.deleteBuffer(buffer);
                    
                    // 编写着色器
                    // 通过text属性提取出script元素的内容
                    let vertexGlsl=document.getElementById('vertexShader').text;
                    let fragmentGlsl=document.getElementById('fragmentShader').text;
                    
                    // 取得了GLSL字符串后，接下来就是创建着色器，传入着色器的类型
                    var vertexShader=gl.createShader(gl.VERTEX_SHADER);
                    gl.shaderSource(vertexShader,vertexGlsl);

                    // 编译着色器
                    gl.compileShader(vertexShader);
                    // 检测是否编译成功
                    if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){
                        console.log(gl.getShaderInfoLog(vertexShader));
                    }
                    
                    var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
                    gl.shaderSource(fragmentShader,fragmentGlsl);
                    gl.compileShader(fragmentShader);

                    // 以上代码创建了两个着色器,使用下列代码可以把这两个对象链接到着色器程序中
                    var program=gl.createProgram();
                    gl.attachShader(program,vertexShader);
                    gl.attachShader(program,fragmentShader);
                    gl.linkProgram(program);
                    // 检测是否链接成功
                    if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
                        console.log(gl.getProgramInfoLog(program));
                    }
                    gl.useProgram(program);
                    
                    // 前面定义的着色器必须接受一个值才能正常工作
                    // 找到这个变量位置,基于这个变量的位置赋值
                    var uColor=gl.getUniformLocation(program,'uColor');
                    gl.uniform4fv(uColor,[0,0,0,1]);
                    
                    // 同理找到位置
                    var aVertexPosition=gl.getAttribLocation(program,'aVertexPosition');
                    // 启用它
                    gl.enableVertexAttribArray(aVertexPosition);
                    // 创建了指针,指向gl.bindBuffer()指定的缓冲区，并将其保存在aVertexPosition中以便顶点着色器使用
                    gl.vertexAttribPointer(aVertexPosition,itemSize,gl.FLOAT,false,0,0);
                }else{
                    console.log("不支持gl")
                }
            }
        })();
    }
</script>

</html>